/*
 * game.h
 *
 * This has all the constants for the game
 *
 *  Created on: Dec 8, 2011
 *      Author: Jonathan Marokhovsky
 */

#ifndef GAMESERVER_H_
#define GAMESERVER_H_

/* Size Constants */
#define MAP_WIDTH		46
#define MAP_HEIGHT		16
#define INSTRUCT_HEIGHT	1
#define PL_INFO_HEIGHT	5
#define TOTAL_HEIGHT	(MAP_HEIGHT + INSTRUCT_HEIGHT + PL_INFO_HEIGHT)

#define UPDATE_RATE		100000 // microseconds
#define BULLET_SPEED	1	// spaces per frame sent
#define MAX_PLAYERS		10
#define MAX_BULLETS		30 // three bullets per person for now
#define MAX_SCORE		9
#define MAX_DEATHS		99

char theOriginalMap[] = 	   {	"______________________________________________\n"
							"______________________________________________\n"
							"______________________________________________\n"
							"______________________________________________\n"
							"______________________________________________\n"
							"----------------------------------------------\n"
							"|               |           |                |\n"
							"|               |           |                |\n"
							"|               |           |                |\n"
							"|               |-- --|     |                |\n"
							"|                     |     |                |\n"
							"|                     |     |                |\n"
							"|                     |     |                |\n"
							"|                     |     |                |\n"
							"|                     |     |                |\n"
							"|                     |-----|                |\n"
							"|                                            |\n"
							"|                                            |\n"
							"|                                            |\n"
							"|                                            |\n"
							"----------------------------------------------\n"
							"     W, A, S, D to move, I, J, K, L to shoot    "};


typedef enum DIRECTION {
		NORTH,
		WEST,
		SOUTH,
		EAST
} Direction;

typedef struct pnt {
	int x;
	int y;
} Point;

/*
 * Info that must be contained in a player:
 * 		avatar
 * 		position (x,y)
 * 		name
 * 		IP address
 * 		port
 * 		score array (kill:death)
 */
//int maxNameLength = MAX_NAME_LEN;
typedef struct player_info {
	char avatar;
	Point position;
	char *ip;
	int port;
	int score[2];
	char *name; // this should be the max name length
} Player;

/*
 * Info that must be contained in a bullet:
 *		position (x,y)
 *		playerID that shot it
 */
typedef struct bull_info {
	Point position;
	int pID;
	Direction dir;
} Bullet;

/*
 * This function takes in the player information, makes a new Player struct for it, adds it to the
 * player array, and updates the player count.
 *
 * If the player was successfully added this returns 0, otherwise it returns 1
 */
int newPlayer(char av, char *name, char *ip, int port, Player playerArrayPt[]);

/*
 * This function adds the player to the score board
 */
int addPlayerToScoreBoard(Player player, int playerCount);

/*
 * This function makes a new Bullet with the given information, adds it to the list of bullets, and
 * updates the bullet count.
 *
 * the player variable is what number the player who shot the bullet is in the player array.
 */
void shotFired(int player, Direction dir, Point playerPos);


/*
 * This function sends out maps to every one in the list of players
 */
void updateMap(int signal);

/*
 * This function removes the player which has the given avatar
 */
int removePlayer(char av);

/*
 * This function finds a player by it's avatar.
 *
 * This returns the index number of the player if it was found, if not found it returns -1.
 */
int findPlayer(char av);

/*
 * This function attempts the given action, if the action is invalid the function does nothing, if
 * the move is valid then the function updates the map.
 */
void attemptAction(char av, char cmd);

/*
 * This moves the given player from  the from Point to the to Point.
 */
void movePlayer(char av, Point from, Point to);

/*
 * This checks that the character belongs to a valid player and if it does, add a death to that
 * player and a kill to the shooter (the index of which is supplied).
 *
 * It is assumed that by the time it has gotten to this point, the bullet has been deleted off the
 * map.
 */
void checkHit(char av, int playerIndex);

/*
 * This checks whether the given player won.
 */
void checkWin(Player player);

/*
 * This checks whether the given player has lost.
 */
void checkLose(Player player);

/*
 * The given player has won, print a message to all
 */
void winAndRestart(Player winner);

/*
 * The given player has lost so miserably the game needs to restart
 */
void loseAndRestart(Player loser);

/*
 * Reset everything in the game.
 */
void restartGame();

/*
 * This is a function to initialize the given avatar's position.
 *
 * This does not change the player information so that must be done outside using the returned
 * Point.
 */
Point initializePosition(char av);


int newPlayerSocket(char ip[], int port);

/*
 * This converts an (x,y) coordinate to line up with a 1d char[]
 */
int convertPoint(Point thePoint)
{
	int ret;
	int yMax = TOTAL_HEIGHT;
	int xMax = MAP_WIDTH + 1; // The +1 is for the \n at the end of every line
	int y = thePoint.y;
	int x = thePoint.x;
	ret = (yMax - (y % (yMax + 1))) * (xMax + 1) + x;
	return ret;
}
#endif /* GAMESERVER_H_ */
